home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * General routines to handle the graphics. *
- * *
- * Written by: Gershon Elber Ver 0.1, Oct. 1989 *
- * *
- * Support: Interface for the virtual device driver. *
- *****************************************************************************/
-
- #define SUPPORT_GIF /* Dump it out as GIF file. */
-
- #ifdef SUPPORT_GIF
- #include "gif_lib.h"
- #endif /* SUPPORT_GIF */
-
- #include <stdio.h>
- #include "virtrstr.h"
- #include "program.h"
- #include "igraph.h"
-
- /* #define DEBUG Dump virtual screen to Hercules graphic device. */
-
- #ifdef __MSDOS__
- #include <io.h>
- #include <fcntl.h>
- #include <bios.h>
- #include <dos.h>
- #include <conio.h>
- #endif /* __MSDOS__ */
-
- #define EPSON_SIZE_X 1024
- #define EPSON_SIZE_Y 640
- #define EPSON_SIZE_MAX 1024 /* The maximum of the two above. */
- #define EPSON_SIZE_X2 (EPSON_SIZE_X / 2)
- #define EPSON_SIZE_Y2 (EPSON_SIZE_Y / 2)
-
- /* The epson specific are defined here: */
- #define EPSON_WIDTH 80 /* 80 char per line. */
- #define EPSON_PIXEL_2_CHAR 8 /* 8 pixels per char, in REG_DENSITY. */
-
- #define EPSON_ESC "\x1b" /* Actually regular escape char. */
- #define EPSON_RESET "\x1b\x40" /* Reset the printer - ESC @. */
- #define EPSON_VERTICAL_SPACE "\x1b\x41\x08" /* 8/72 vert. - ESC A 0x08. */
- #define EPSON_REG_DENSITY "\x1b\x4b" /* 640 pixels per 7.5" - ESC K. */
- #define EPSON_DUAL_DENSITY "\x1b\x4c" /* 1280 pixels per 7.5" - ESC L. */
-
- static int GraphicMode = FALSE;
-
- static void PutString(int DirectPrint, char *Str, int Len);
- static void PutString2(int DirectPrint, char *Str, int Len);
-
- #ifdef __MSDOS__
- #ifdef DEBUG
- static void DisplayBufferOnHercules(void);
- static void HercGraphics(void);
- static void HercPutPoint(int x, int y);
- static void HercText(void);
- #endif /* DEBUG */
- #endif /* __MSDOS__ */
-
- /****************************************************************************
- * Routine to reset all the system to starting condition : *
- ****************************************************************************/
- void IGInitGraph(void)
- {
- if (!VirtInit(EPSON_SIZE_X, EPSON_SIZE_Y)) {
- fprintf(stderr, "Failed to allocate virtual device (no memory).\n");
- MyExit(1);
- }
- GraphicMode = TRUE;
- }
-
- /****************************************************************************
- * Routine to close and shutdown graphic mode : *
- ****************************************************************************/
- void IGCloseGraph(void)
- {
- if (GraphicMode) {
- VirtClose();
- GraphicMode = FALSE;
- }
- }
-
- /****************************************************************************
- * Routine to dump the screen to the desired output device. *
- ****************************************************************************/
- void IGDumpScreen(OutputDriverType OutputKind, int DirectPrint,
- BooleanType DoubleDensity)
- {
- #ifdef SUPPORT_GIF
- static GifColorType GifColorMap[] = { { 0, 0, 0 }, { 255, 255, 255 } };
- GifFileType *GifFile;
- #endif /* SUPPORT_GIF */
- int i, j, k, Count;
- unsigned int Shift;
- char LineBuffers[8][EPSON_SIZE_Y / 8 + 1], OutputBuffer[EPSON_SIZE_MAX],
- LinePrefixLen[2];
-
- switch (OutputKind) {
- case OUTPUT_EPSON:
- if (DirectPrint != 0) break;
-
- #ifdef __MSDOS__
- /* Make sure stdout is output for binary output and buffer it. */
- setmode(1, O_BINARY);
- #endif /* __MSDOS__ */
- break;
- #ifdef SUPPORT_GIF
- case OUTPUT_GIF:
- if ((GifFile = EGifOpenFileHandle(1)) == NULL) {
- fprintf(stderr, "Failed to open gif file.\n");
- MyExit(-1);
- }
- break;
- #endif /* SUPPORT_GIF */
- case OUTPUT_RAW:
- #ifdef __MSDOS__
- /* Make sure stdout is output for binary output and buffer it. */
- setmode(1, O_BINARY);
- #endif /* __MSDOS__ */
- break;
- default:
- fprintf(stderr, "Output kind is not supported, exit.\n");
- MyExit(-1);
- }
-
- #ifdef __MSDOS__
- #ifdef DEBUG
- DisplayBufferOnHercules();
- return;
- #endif /* DEBUG */
- #endif /* __MSDOS__ */
-
- switch (OutputKind) {
- case OUTPUT_EPSON:
- fprintf(stderr, "Dumping line [%d]: ", EPSON_SIZE_X);
-
- /* Reset printer, and make sure no space between adjacent lines: */
- PutString(DirectPrint, EPSON_RESET, 2);
- PutString(DirectPrint, EPSON_VERTICAL_SPACE, 3);
-
- for (i = 0; i < EPSON_SIZE_X; i += 8) { /* Dump 8 lines at once: */
- fprintf(stderr, "\b\b\b\b%-4d", i);
-
- for (j = 0; j <8; j++)
- VirtGetBlock(i + j, 0, i + j, EPSON_SIZE_Y, LineBuffers[j]);
-
- Shift = 1;
- Count = EPSON_SIZE_Y / 8;
- for (j = 0; j < EPSON_SIZE_Y; j++) {
- OutputBuffer[j] = 0;
- for (k = 0; k < 8; k++) {
- OutputBuffer[j] <<= 1;
- if (LineBuffers[k][Count] & Shift) OutputBuffer[j]++;
- }
- if ((Shift <<= 1) == 256) {
- Shift = 1;
- Count--;
- }
- }
- /* Find last position of non empty pixel byte: */
- for (j = EPSON_SIZE_Y - 1; j >= 0; j--)
- if (OutputBuffer[j] != 0) break;
-
- if (j != 0 || OutputBuffer[0] != 0) {
- j++;
- if (DoubleDensity) {
- PutString(DirectPrint, EPSON_DUAL_DENSITY, 2);
- LinePrefixLen[0] = (j * 2) % 256;
- LinePrefixLen[1] = (j * 2) / 256;
- PutString(DirectPrint, LinePrefixLen, 2);
- PutString2(DirectPrint, OutputBuffer, EPSON_SIZE_Y);
- }
- else {
- PutString(DirectPrint, EPSON_REG_DENSITY, 2);
- LinePrefixLen[0] = j % 256;
- LinePrefixLen[1] = j / 256;
- PutString(DirectPrint, LinePrefixLen, 2);
- PutString(DirectPrint, OutputBuffer, EPSON_SIZE_Y);
- }
- }
- PutString(DirectPrint, "\x0d\x0a", 2);
- }
- break;
- case OUTPUT_RAW:
- fprintf(stderr, "Dumping line [%d]: ", EPSON_SIZE_X);
-
- for (i = 0; i < EPSON_SIZE_X; i++) {
- fprintf(stderr, "\b\b\b\b%-4d", i);
- VirtGetBlock(i, 0, i, EPSON_SIZE_Y, LineBuffers[0]);
- for (j = 0; j < EPSON_SIZE_Y / 8; j++)
- putchar(LineBuffers[0][j]);
- }
- break;
- #ifdef SUPPORT_GIF
- case OUTPUT_GIF:
- fprintf(stderr, "Dumping line [%d]: ", EPSON_SIZE_Y);
-
- if (EGifPutScreenDesc(GifFile, EPSON_SIZE_X, EPSON_SIZE_Y, 1, 0, 1,
- GifColorMap) == GIF_ERROR ||
- EGifPutImageDesc(GifFile, 0, 0, EPSON_SIZE_X, EPSON_SIZE_Y,
- FALSE, 1, NULL) == GIF_ERROR) {
- fprintf(stderr, "Failed to write to gif file.\n");
- MyExit(-1);
- }
-
- for (i = 0; i < EPSON_SIZE_Y; i++) {
- fprintf(stderr, "\b\b\b\b%-4d", i);
- VirtGetBlock(0, i, EPSON_SIZE_X, i, LineBuffers[0]);
- Shift = 1;
- Count = EPSON_SIZE_X / 8;
- for (j = EPSON_SIZE_X; j >= 0; j--) {
- OutputBuffer[j] = (LineBuffers[0][Count] & Shift) != 0;
- if ((Shift <<= 1) == 256) {
- Shift = 1;
- Count--;
- }
- }
- if (EGifPutLine(GifFile, (GifPixelType *) OutputBuffer,
- EPSON_SIZE_X) == GIF_ERROR) {
- fprintf(stderr, "Failed to write to gif file.\n");
- MyExit(-1);
- }
- }
- if (EGifCloseFile(GifFile) == GIF_ERROR) {
- fprintf(stderr, "Failed to close gif file.\n");
- MyExit(-1);
- }
- break;
- #endif /* SUPPORT_GIF */
- }
- }
-
- /******************************************************************************
- * Dumps the string of given length, to Prt. No char in Str has special *
- * meaning, and even zero (NULL) chars are dumped. *
- * If however DirectPrint is non zero, string is dumped to specifed lpt port. *
- ******************************************************************************/
- static void PutString(int DirectPrint, char *Str, int Len)
- {
- int i;
-
- if (DirectPrint != 0) {
- #ifdef __MSDOS__
- for (i = 0; i < Len; i++) biosprint(0, Str[i], DirectPrint - 1);
- #else
- fprintf(stderr, "Output kind is not supported, exit.\n");
- MyExit(-1);
- #endif /* __MSDOS__ */
- }
- else
- fwrite(Str, Len, 1, stdout);
- }
-
- /******************************************************************************
- * Dumps the string of given length, to Prt. No char in Str has special *
- * meaning, and even zero (NULL) chars are dumped. Every char is dumped twice. *
- * If however DirectPrint is non zero, string is dumped to specifed lpt port. *
- ******************************************************************************/
- static void PutString2(int DirectPrint, char *Str, int Len)
- {
- int i;
-
- if (DirectPrint != 0) {
- #ifdef __MSDOS__
- for (i = 0; i < Len; i++) {
- biosprint(0, Str[i], DirectPrint - 1);
- biosprint(0, Str[i], DirectPrint - 1);
- }
- #else
- fprintf(stderr, "Output kind is not supported, exit.\n");
- MyExit(-1);
- #endif /* __MSDOS__ */
- }
- else {
- for (i = 0; i < Len; i++) {
- putchar(Str[i]);
- putchar(Str[i]);
- }
- }
- }
-
-
- /****************************************************************************
- * Routine to map drawing x coordinate into screen space. *
- ****************************************************************************/
- int IGMapX(int x)
- {
- return x >> IG_DEFAULT_ZOOM_FACTOR;
- }
-
- /****************************************************************************
- * Routine to map drawing y coordinate into screen space. *
- ****************************************************************************/
- int IGMapY(int y)
- {
- return y >> IG_DEFAULT_ZOOM_FACTOR;
- }
-
- /****************************************************************************
- * Routine to move to a new position, as in Drawing space. *
- ****************************************************************************/
- void IGMoveTo(int x, int y)
- {
- VirtMoveTo(IGMapX(x), IGMapY(y));
- }
-
- /****************************************************************************
- * Routine to draw to a new position, as in Drawing space. *
- ****************************************************************************/
- void IGLineTo(int x, int y)
- {
- VirtLineTo(IGMapX(x), IGMapY(y));
- }
-
- /****************************************************************************
- * Routine to draw a line between the two given points. *
- ****************************************************************************/
- void IGLine(int x1, int y1, int x2, int y2)
- {
- VirtMoveTo(IGMapX(x1), IGMapY(y1));
- VirtLineTo(IGMapX(x2), IGMapY(y2));
- }
-
- /****************************************************************************
- * Routine to draw a new polyline and fill it if Fill. *
- ****************************************************************************/
- void IGPoly(int n, int *Points, int Fill)
- {
- int i;
- static PrintedWarning = FALSE;
-
- VirtMoveTo(IGMapX(Points[0]), IGMapY(Points[1]));
- for (i = 1; i < n; i++) {
- VirtLineTo(IGMapX(Points[i * 2]), IGMapY(Points[i * 2 + 1]));
- }
- if (Fill) {
- if (!PrintedWarning) {
- fprintf(stderr, "Warning: polygon fill not supported - ignored.\n");
- PrintedWarning = TRUE;
- }
- }
- }
-
- /****************************************************************************
- * Routine to draw a bar, as in Drawing space. *
- ****************************************************************************/
- void IGBar(int x1, int y1, int x2, int y2)
- {
- VirtBar(IGMapX(x1), IGMapY(y1), IGMapX(x2), IGMapY(y2));
- }
-
- /****************************************************************************
- * Routine to draw a circle, as in Drawing space. *
- ****************************************************************************/
- void IGCircle(int x, int y, int r)
- {
- VirtCirc(IGMapX(x), IGMapY(y), r >> IG_DEFAULT_ZOOM_FACTOR);
- }
-
- /****************************************************************************
- * Routine to draw an arc, as in Drawing space. *
- * As the Y axes is inverted the Angles should be inverted as well. *
- ****************************************************************************/
- void IGArc(int x, int y, int StAngle, int EndAngle, int r)
- {
- VirtArc(IGMapX(x), IGMapY(y), r >> IG_DEFAULT_ZOOM_FACTOR,
- StAngle, EndAngle);
- }
-
- /****************************************************************************
- * Routine to draw the given text in current cursor position. *
- ****************************************************************************/
- void IGText(char *s)
- {
- VirtText(s);
- }
-
- /****************************************************************************
- * Routine to draw the not bar above a negated text. *
- ****************************************************************************/
- void IGDrawNotBar(int x1, int y1, int x2, int y2, char *Str)
- {
- IGMoveToNoMap(x1, y1);
- IGLineRelToNoMap(x2, y2);
- }
-
- /****************************************************************************
- * Routine to set attributes - horiz./vert. and centering. *
- ****************************************************************************/
- void IGTextFormat(TextOrientationType Orient, int Scale,
- TextHorizJustifyType XCenter, TextVertJustifyType YCenter)
- {
- VirtTextFormat(Orient, Scale, XCenter, YCenter);
- }
-
- /****************************************************************************
- * Routine to set color to color within range. *
- ****************************************************************************/
- void IGSetColor(int Color)
- {
- VirtSetColor(Color);
- }
-
- /*****************************************************************************
- * Routine to clear all the screen. *
- *****************************************************************************/
- void IGClearAllScreen(void)
- {
- VirtClear();
- }
-
- /*****************************************************************************
- * Relative line to in screen coordinates. *
- *****************************************************************************/
- void IGLineRelToNoMap(int x, int y)
- {
- VirtLineRelTo(x, y);
- }
-
- /*****************************************************************************
- * Move to in screen coordinates. *
- *****************************************************************************/
- void IGMoveToNoMap(int x, int y)
- {
- VirtMoveTo(x, y);
- }
-
- /*****************************************************************************
- * Line in screen coordinates. *
- *****************************************************************************/
- void IGLineNoMap(int x1, int y1, int x2, int y2)
- {
- VirtLine(x1, y1, x2, y2);
- }
-
- /*****************************************************************************
- * Returns text width in screen coordinates. *
- *****************************************************************************/
- int IGTextWidthNoMap(char *s)
- {
- return VirtTextWidth(s);
- }
-
- /*****************************************************************************
- * Returns text height in screen coordinates. *
- *****************************************************************************/
- int IGTextHeightNoMap(char *s)
- {
- return VirtTextHeight(s);
- }
-
- #ifdef __MSDOS__
- #ifdef DEBUG
-
- /******************************************************************************
- * This routine fetch the vitual frame buffer content and display it on an *
- * hercules device. *
- ******************************************************************************/
- static void DisplayBufferOnHercules(void)
- {
- int i, j, Shift, MaxX, MaxY;
- char ScanLine[256], *p;
-
- MaxX = EPSON_SIZE_X;
- if (MaxX > 720 * 2) MaxX = 720 * 2;
- MaxY = EPSON_SIZE_Y;
- if (MaxY > 350 * 2) MaxY = 350 * 2;
-
- HercGraphics();
-
- for (i = 0; i < MaxX; i += 2) {
- VirtGetBlock(i, 0, i, MaxY - 1, ScanLine);
- p = ScanLine;
- Shift = 256;
- for (j = 0; j < MaxY; j++) {
- if (Shift == 1) {
- Shift = 256;
- p++;
- }
- if (((*p) & (Shift >>= 1)) != 0)
- HercPutPoint(i >> 1, j >> 1);
- }
- }
-
- sound(1000);
- delay(100);
- nosound();
-
- getch();
-
- HercText();
- }
-
- /******************************************************************************
- * Go to hercules graphic mode, page 1, and clear the screen. *
- ******************************************************************************/
- static void HercGraphics(void)
- {
- static int far *HerculesScreen = MK_FP(0xb000, 0x0000);
- static unsigned char GraphModeRegs[] =
- { 53,45,46, 8,91, 2,87,87, 2, 3, 0, 0, 0, 0, 0, 0 };
- int i;
-
- outportb(0x3bf, 0x01);
- outportb(0x3b8, 0x00);
-
- for (i=0; i<12; i++) {
- outportb(0x3b4, i);
- outportb(0x3b5, GraphModeRegs[i]);
- }
-
- outportb(0x3b8, 0x2a);
-
- for (i=0; i<16384; i++) HerculesScreen[i] = 0x0000;
- }
-
- /******************************************************************************
- * Plot one point at x, y on the hercules page 1 screen. *
- ******************************************************************************/
- static void HercPutPoint(int x, int y)
- {
- static char far *HerculesScreen = MK_FP(0xb000, 0x0000);
- int Bit = x & 0x07, Byte = x >> 3, Page = y & 0x03, PageY = y >> 2;
-
- HerculesScreen[Page * 0x2000 + PageY * 90 + Byte] |= 128 >> Bit;
- }
-
- /******************************************************************************
- * Go to hercules text mode. *
- ******************************************************************************/
- static void HercText(void)
- {
- static int far *HerculesScreen = MK_FP(0xb000, 0x0000);
- static unsigned char TextModeRegs[] =
- { 97,80,82,15,25, 6,25,25, 2,13,11,12, 0, 0, 0, 0 };
- int i;
-
- outportb(0x3bf, 0x01);
- outportb(0x3b8, 0x00);
-
- for (i=0; i<12; i++) {
- outportb(0x3b4, i);
- outportb(0x3b5, TextModeRegs[i]);
- }
-
- outportb(0x3b8, 0x28);
-
- for (i=0; i<16384; i++) HerculesScreen[i] = 0x0720;
- }
-
- #endif /* DEBUG */
- #endif /* __MSDOS__ */